using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.Practices.Repository.Configuration
{
    /// <summary>
    /// Configuration collection used by the RepositoryFactorySection to store
    /// the mappings between the interface type and a concrete repository type.
    /// </summary>
    [ConfigurationCollection(typeof(RepositoryElement))]
    public class RepositoryElementCollection : ConfigurationElementCollection
    {
        /// <summary>
        /// Creates a new instance of RepositoryElementCollection.
        /// </summary>
        [SuppressMessage("Microsoft.Design", "CA1010:CollectionsShouldImplementGenericInterface")]
        public RepositoryElementCollection() : base(StringComparer.OrdinalIgnoreCase)
        {

        }

        /// <summary>
        /// Returns a RepositoryElement that has the key type
        /// as interface type.
        /// </summary>
        /// <param name="key">Interface type of the repository</param>
        /// <returns>RepositoryElement.</returns>
        [SuppressMessage("Microsoft.Design", "CA1043:UseIntegralOrStringArgumentForIndexers")]
        public RepositoryElement this[Type key]
        {
            get
            {
                foreach (RepositoryElement element in this)
                {
                    Type currentType = Type.GetType(element.InterfaceType);
                    if (currentType != null)
                    {
                        if (key == currentType)
                        {
                            return element;
                        }
                    }
                }
                return null;
            }
        }

        /// <summary>
        /// Returns a RepositoryElement that has the key type fullname
        /// as interface type.
        /// </summary>
        /// <param name="key">Interface type fullname.</param>
        /// <returns>RepositoryElement.</returns>
        public new RepositoryElement this[string key]
        {
            get
            {
                return (RepositoryElement)base.BaseGet(key);
            }
        }

        /// <summary>
        /// Creates a new RepositoryElement instance.
        /// </summary>
        /// <returns>RepositoryElement.</returns>
        protected override ConfigurationElement CreateNewElement()
        {
            return new RepositoryElement();
        }

        /// <summary>
        /// Returns the key for a given repository element.
        /// </summary>
        /// <param name="element">RepositoryElement.</param>
        /// <returns>The repository interface type name.</returns>
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((RepositoryElement)element).InterfaceType;
        }

        /// <summary>
        /// Adds a RepositoryElement to the RepositoryElementCollection.
        /// </summary>
        /// <param name="element">RepositoryElement to add.</param>
        public void Add(RepositoryElement element)
        {
            base.BaseAdd(element);
        }
    }
}
